﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using HWEngine.Generators;

namespace HWEngine
{
	public enum DrawingMode
	{
		GDIPlus,
		CustomLines,
		CustomPoints,
		CustomMultiLines,
		CustomLinesRounds,
		CustomPointsDelegate
	}

	public enum PaintEventArguments
	{
		Start,
		Point,
		End
	}

	public static class GdiExtensions
	{
		public delegate void PaintEventDelegate(PaintEventArguments type, PointF coords);
		public static PaintEventDelegate PaintEvent;

		public static void Draw(this Line line, Graphics graphics)
		{
			Pen pen = new Pen(line.Color, (float)line.Width);
			if (HWGenerator.CurrentLetterSet == null || HWGenerator.CurrentLetterSet.DrawingMode == DrawingMode.GDIPlus)
			{
				graphics.DrawCurve(pen, line.Points.ToArray(), line.Tension);
			}
			else
			{
				DrawCurveCustom(line, graphics, pen);
			}
			pen.Dispose();
		}

		private static void DrawCurveCustom(Line line, Graphics graphics, Pen pen)
		{
			var result = line.CalculateSpline();

			switch (HWGenerator.CurrentLetterSet.DrawingMode)
			{
				case DrawingMode.CustomMultiLines:
					graphics.DrawLines(pen, result.ToArray());
					break;
				case DrawingMode.CustomPoints:
					foreach (PointF p in result)
					{
						graphics.DrawRectangle(pen, p.X, p.Y, 0.5f, 0.5f);
					}
					break;
				case DrawingMode.CustomLines:
					PointF pf = result.First();
					foreach (PointF p in result)
					{
						graphics.DrawLine(pen, pf, p);
						pf = p;
					}
					break;
				case DrawingMode.CustomLinesRounds:
					PointF pf1 = result.First();
					Brush br = new SolidBrush(pen.Color);
					foreach (PointF p in result)
					{
						graphics.DrawLine(pen, pf1, p);
						float linewidth = pen.Width/2;
						float cw = linewidth;
						graphics.FillEllipse(br, pf1.X - cw, pf1.Y - cw, cw*2, cw*2);
						pf1 = p;
					}
					br.Dispose();
					break;
				case DrawingMode.CustomPointsDelegate:
					if (PaintEvent != null)
					{
						PaintEvent(PaintEventArguments.Start, result.First());
						foreach (PointF p in result)
						{
							if (PaintEvent != null)
							{
								PaintEvent(PaintEventArguments.Point, p);
							}
						}
						if (PaintEvent != null)
						{
							PaintEvent(PaintEventArguments.End, new PointF());
						}
					}
					break;
			}
		}

		public static void Draw(this Letter letter, Graphics graphics)
		{
			foreach (Line line in letter.Lines)
			{
				line.Draw(graphics);
			}
		}
	}
}
